import { reactive } from "vue";
import type { UnPromisify } from "@/util/typescript.ts";

export const isSuccessResult = (code: number) => code === 200;
export const isWarningResult = (code: number) => code < 0;
export const isErrorResult = (code: number) => code > 0;
export const isUnAuthResult = (code: number) => code === 0;


interface UseRequestOptions<T> {
    /**
     * 默认值, 未请求、请求失败、无响应数据都将会采用该值
     */
    defaultValue?: T
}

export interface UseRequestResult<T, F> {
    /**
     * 响应信息
     */
    response: {
        /**
         * 响应结果
         */
        result: T | undefined,
        /**
         * 是否请求中
         */
        waiting: boolean
    },
    /**
     * 执行请求
     */
    request: F
}

/**
 * 封装请求, 返回常规的响应式对象
 *
 * @param executor 请求执行方法
 * @param options 选项参数
 */
export function useRequest<
    F extends (this: any, ...args: any[]) => Promise<any>,
    T = UnPromisify<ReturnType<F>>
>(executor: F, options?: UseRequestOptions<T>): UseRequestResult<T, F> {
    const response: UseRequestResult<T, F>["response"] = reactive({
        result: options?.defaultValue as any,
        waiting: false
    });
    // @ts-ignore
    const request: F = function (...args: any[]) {
        if (response.waiting) {
            return Promise.reject("Request not terminated");
        }
        response.waiting = true;
        return executor.apply(this, args)
            .then(res => {
                response.result = res;
                return res;
            }).finally(() => {
                response.waiting = false;
            });
    }

    return {
        response,
        request
    }
}